home *** CD-ROM | disk | FTP | other *** search
- /*
- ** AIFF_CD.h - header file defining both chunks of the AIFF-CD standard in C
- ** and the standard itself
- **
- ** $Id: AIFF_CD.h 1.6 1998/11/02 11:52:47 patrick Rel patrick $
- **
- ** $Log: AIFF_CD.h $
- ** Revision 1.6 1998/11/02 11:52:47 patrick
- ** added the authors mail address
- **
- ** Revision 1.5 1998/11/02 11:46:02 patrick
- ** External filenames are explicitely required to follow the Amiga convations.
- ** Added explanation of this convention.
- **
- ** Revision 1.4 1998/07/02 11:45:56 patrick
- ** added RCS logging
- **
- **
- ** Revision 1.3:
- ** added example
- ** Revision 1.2:
- ** added macros to step between ACD_TRInfos
- ** Revision 1.1:
- ** initial revision
- **
- ** ©1998 Patrick Ohly, Patrick.Ohly@gmx.de
- */
-
- #ifndef AIFF_CD_H
- #define AIFF_CD_H
-
- /*
- ** CD-ROM extensions to AIFF[-C] standard
- ** ======================================
- **
- ** 1. Introduction
- ** ---------------
- **
- ** The intention of this document is to define an extension to the AIFF and
- ** AIFC data file format that allows such files to represent all informations
- ** relevant to an audio and mixed-mode CD (data track + audio tracks).
- **
- ** Knowledge about these two standards and IFF are expected. This document uses
- ** the same data type notation as in those standards. AIFF is used as a synonym
- ** for both AIFF and AIFC from now on.
- **
- ** This documents's main focus are definitely audio CDs. It does not try to
- ** represent all possible types of CDs, only those that consist of one session,
- ** consecutive audio tracks plus one optional data track at the beginning.
- ** ".aiff-cd" and ".aifc-cd" should be used as suffices for this new file
- ** format.
- **
- ** The audio tracks are stored in the usual AIFF way and can have any format
- ** valid for AIFF. It is up to applications to cope with different number of
- ** channels, bits per sample, and frequency correctly.
- **
- ** This approach has the advantage that existing audio applications can access
- ** the audio data without any modifications in the program. It has the
- ** disadvantage that the audio data has to be copied, too.
- **
- ** Therefore the audio data for each track may alternatively be stored in
- ** another file that is only referenced by the AIFF-CD file. The contents of
- ** this other file is not defined by this standard.
- **
- ** Applications aware of the CD-ROM extensions may store the following
- ** informations:
- ** - International Standard Recording Code (ISRC) and other
- ** advanced information for some or all tracks
- ** - Medium Catalog Number for the CD
- ** - Index markers within each track
- ** - one data track
- **
- ** These extensions are stored in local chunks within the AIFF
- ** form. They are defined in the following chapter. They are illustrated
- ** by an example at the end of this document.
- **
- ** 2. Chunk Definitions
- ** --------------------
- **
- ** All of these chunks are optional. It is up to an application to use
- ** reasonable default values, if necessary. The following data types
- ** are used in this standard:
- */
-
- typedef unsigned long ACD_Block; /* logical CD block,
- 1min = 60s, 1s = 75 blocks,
- block #0 == 00:02:00 min:sec:frame */
- typedef unsigned long ACD_AudioBlock; /* as above, but now relative to beginning
- of the audio sample:
- block #0 == 0.0 sec of audio sample */
- typedef unsigned long ACD_SampleNum; /* position within an audio sample or
- amount of audio data;
- this value is independent from the
- number of channels, i.e. multiple
- samples played in parallel only count
- as one sample */
- typedef unsigned long ACD_ULONG; /* 32 bit integer, unsigned */
- typedef signed long ACD_LONG; /* 32 bit integer, signed */
- typedef ACD_ULONG ACD_ID;
-
- /*
- ** Some more types as defined in the AIFF standard are used in the
- ** definition of chunks. Any definition not allowed in C (variable sized
- ** arrays, pstrings, ... ) are excluded using
- ** #ifdef ACD_NON_C_DATATYPES
- ** ...
- ** #endif.
- ** Take care to handle those entries in the chunks correctly in your code.
- **
- ** These are chunks required for AIFF and AIFC. They are included for
- ** your convenience only and are explained in the corresponding standards.
- */
-
- typedef struct {
- unsigned short exponent; /* Exponent, bit #15 is sign bit for mantissa */
- unsigned long mantissa[2]; /* 64 bit mantissa */
- } extended;
-
- typedef struct
- {
- SHORT numChannels;
- ULONG numSampleFrames;
- SHORT sampleSize;
- extended sampleRate;
- } AIFF_CommonChunk;
-
- typedef struct
- {
- SHORT numChannels;
- ULONG numSampleFrames;
- SHORT sampleSize;
- extended sampleRate;
- ULONG compression_ID;
- } AIFC_CommonChunk;
-
- typedef struct
- {
- ULONG offset;
- ULONG blocksize;
- } AIF_SoundData;
-
-
- /*
- ** 2.1 Track Information
- ** ^^^^^^^^^^^^^^^^^^^^^
- **
- ** For each track its source and type can be defined independently. The data can either
- ** be contained in the SSND chunk of the AIFF-CD file itself or in the file refered to
- ** in the track entry. If an external file is used then it is up to the application to
- ** recognize the format. In both cases the relevant data may be some subpart of the
- ** source defined by start and length.
- */
-
-
- #define ACD_TRI_PREAMPHASIZE (1<<0) /* audio data was sampled with preamphasize */
- #define ACD_TRI_COPYRIGHTED (1<<1) /* data has a copyright */
- #define ACD_TRI_EXTERNAL (1<<2) /* data is stored in an external file */
- #define ACD_TRI_PAUSE (1<<3) /* last entry in index list marks a pause */
-
- typedef struct {
- ACD_ULONG pause; /* This number of empty blocks shall be generated
- before the track when writing to CD-R; usually 0.
- This data will be part of the pregap. */
- ACD_SampleNum start; /* beginning and */
- ACD_SampleNum length; /* length of the audio data taken from the source(s) */
- ACD_ULONG flags; /* ACD_TRI_#? as defined above */
-
- ACD_ULONG numIndices; /* Indices are given relative to the beginning of
- the real audio data of this track (i.e. 'start').
- Index #1 always starts at 0 and has to be omitted.
- The last entry is the beginning of the index pause
- if ACD_TRI_PAUSE is set, otherwise just another index. */
-
- /* Entry may be extended in the future by a variable number of bytes;
- this is the number of bytes appended to this structure at the end in
- reserved[]. */
- ACD_ULONG numReservedBytes; /* 0 at the moment */
-
-
- #ifdef ACD_NON_C_DATATYPES
- ACD_AudioBlock indices[];
-
- /* only used with ACD_TRI_EXTERNAL, but always present;
- filename can be absolute or relativ to the
- directory the AIFF-CD file is stored in.
-
- AIFF-CD follows the Amiga filename conventions:
- [[»volume«]:][[»dir«]/]*»filename«
-
- »volume«, »dir« and »filename« are 8 bit characters
- without colon (":") and slash ("/"). Absolute paths
- are specified with the optional volume name followed
- by a colon. The colon alone refers to the root directory
- of the filesystem that contains the AIFF-CD file. The
- usage of the absolute part of the filename on non-Amiga
- systems is not specified.
-
- The path specification is similar to Unix, with only one
- exception: a slash without a preceeding directory name
- refers to the parent directory.
- E.g. "dir1/dir2//file" = "dir1/file"
- "/" = parent directory of current directory
- */
-
- pstring externalFile[];
-
- byte reserved[]; /* just skip these bytes if the contents is unknown */
- #endif
- } ACD_TRInfo;
-
- /*
- ** Going from one ACD_TRInfo to the next is a bit tricky because of the
- ** variable sized entries at the end. These macros can be used in C to get
- ** pointers to the first ACD_TRInfo, all following ones and indices[]/
- ** externalFile[]/reserved[].
- **
- ** ACD_FIRST_TRINFO() expects a pointer to the ACD_TRInfoChunk structures
- ** as defined below, including all the data of the chunk. The chunk header
- ** has to be part of this data if and only if ACD_CHUNK_HEADER was defined
- ** to include it in the C structure, too.
- **
- ** The same applies to the other macros which expect a pointer to
- ** ACD_TRInfo.
- */
-
- #define ACD_FIRST_TRINFO(tr_infos) \
- ((ACD_TRInfo *) &((ACD_TRInfoChunk *)tr_infos)[1]) /* skip general infos */
-
- #define ACD_TRINFO_INDICES(tr_info) \
- ((ULONG *) &((ACD_TRInfo *)tr_info)[1]) /* skip track specific infos of constant length */
-
- #define ACD_TRINFO_EXTERNAL(tr_info) \
- ((UBYTE *) &ACD_TRINFO_INDICES(tr_info)[((ACD_TRInfo *)tr_info)->numIndices])
- /* start at indices and skip all of them */
-
- #define ACD_TRINFO_NEXT(tr_info) \
- ((ACD_TRInfo *) &ACD_TRINFO_EXTERNAL(tr_info)[ACD_TRINFO_EXTERNAL(tr_info)[0] + \
- ((ACD_TRINFO_EXTERNAL(tr_info)[0] % 2) ? 1 : 2) + \
- ((ACD_TRInfo *)tr_info)->numReservedBytes])
- /* start at external file name,
- skip the name itself,
- the length byte and the optional pad byte
- and finally the reserved bytes */
-
-
- /*
- ** The different TRInfos are gathered in one obligatory chunk:
- */
-
- #define ACD_TRINFOID 'TRIF'
-
- typedef struct {
- #ifdef ACD_CHUNK_HEADER
- ACD_ID ckID; /* 'TRIF' */
- ACD_LONG ckDataSize;
- #endif
-
- ULONG version; /* 1 at the moment - don't accept versions you don't know,
- any other chunk might have changed */
- ACD_ULONG firstTrackNum; /* the first track number can be chosen, the following
- once increase in steps of one */
- ACD_ULONG numTRInfos;
- #ifdef ACD_NON_C_DATATYPES
- TRInfo TRInfos[];
- #endif
- } ACD_TRInfoChunk;
-
-
- /*
- ** 2.2 ISRC
- ** ^^^^^^^^
- **
- ** For each track at most one ISRC can be specified. Tracks are referenced by
- ** their index in the track info array, not by what they would have on CD.
- ** Only some characters are allowed for the four components of an ISRC. Each
- ** component has to consist of exactly the right number of characters.
- */
-
- typedef char ACD_AZASCII; /* ASCII value of characters A-Z */
- typedef char ACD_AZ09ASCII; /* ASCII value of characters 0-9 and A-Z */
- typedef char ACD_09ASCII; /* ASCII value of characters 0-9 */
-
- typedef struct {
- ACD_ULONG track; /* the same as in the CDMarkers */
- ACD_AZASCII country[2]; /* country code */
- ACD_AZ09ASCII owner[3]; /* owner code */
- ACD_09ASCII year[2]; /* year of recording */
- ACD_09ASCII serial[5]; /* serial number assigned by owner */
- } ACD_ISRC;
-
- /*
- ** The different ISRCs are gathered in one optional chunk.
- ** Not every track must have an ISRC, but entries have to be
- ** sorted on the track number in increasing order.
- */
-
- #define ACD_ISRCID 'ISRC'
-
- typedef struct {
- #ifdef ACD_CHUNK_HEADER
- ACD_ID ckID; /* 'ISRC' */
- ACD_LONG ckDataSize;
- #endif
-
- ACD_ULONG numISRCs;
- #ifdef ACD_NON_C_DATATYPES
- ISRC ISRCs[];
- #endif
- } ACD_ISRCChunk;
-
-
- /*
- ** 2.3 Medium Catalog Number
- ** ^^^^^^^^^^^^^^^^^^^^^^^^^
- **
- ** This optional chunk stores the UPC/EAN number of the CD. The same rules
- ** for valid characters and length as for ISRC apply.
- */
-
- #define ACD_MCNID 'MCNU'
-
- typedef struct {
- #ifdef ACD_CHUNK_HEADER
- ACD_ID ckID; /* 'MCNU' */
- ACD_LONG ckDataSize;
- #endif
-
- ACD_09ASCII MCNum[13]; /* Medium Catalog Number */
- ACD_09ASCII pad;
- } ACD_MCNChunk;
-
-
- /*
- ** 2.4 Data Track
- ** ^^^^^^^^^^^^^^
- **
- ** This optional chunk is not relevant for audio applications. It is used
- ** by CD writer software to allow the user to store the image of a
- ** complete CD in one file. An audio application should copy this chunk
- ** unchanged when writing back a AIFF-CD file or warn the user if it is
- ** not able to do so.
- **
- ** Different types of data can be stored and different data formats are
- ** allowed. More types may be defined latter. An applications should be
- ** prepared to issue a meaningful warning (perhaps using the data type and
- ** format names specified in the chunk) if unknown or unsupported data is
- ** found.
- */
-
- typedef enum {
- ACD_MODE1, /* CD-ROM mode 1 (block size 2048 bytes) */
- ACD_MODE2, /* CD-ROM mode 2 (2336 bytes) */
- ACD_MODE2_FORM1, /* XA mode 2, form 1 (2048 bytes) */
- ACD_MODE2_FORM2 /* XA mode 2, form 2 (2324 bytes) */
- } ACD_DataType;
-
- typedef enum {
- ACD_DF_COOKED, /* only user data with block size as specified above */
- ACD_DF_RAW /* complete block of 2352 bytes, containing user data,
- sync, (sub) header and EDC/EDD as specified in the MMC
- standard; not scrambled */
- } ACD_DataFormat;
-
- /*
- ** These enumerations have the following English names:
- */
-
- #ifdef ACD_NAMES
- char *ACD_TypeNames[] = {
- "Mode 1",
- "Mode 2",
- "Mode 2, Form 1",
- "Mode 2, Form 2"
- };
-
- char *ACD_FormatNames[] = {
- "cooked",
- "raw"
- };
- #endif
-
- /*
- ** The data track contains data with the block size specified by type and
- ** format. This data is placed in a chunk on its own to allow seperate
- ** writing of the data and the control information. The number of blocks
- ** is deduced from the length of this chunk and the block size.
- **
- ** The track starts on the CD at a specific logical CD
- ** block ("startBlock") and must not be relocated without appropriate warnings or
- ** transformations. The data may contain some blocks ("preGapLen") that are
- ** already part of the pregap between the data track and the following audio
- ** track. This pregap is described by the logical CD block number where the
- ** the second, audio part starts ("audioPregapStart") and the logical CD block
- ** number where the audio data is placed ("audioStart"):
- **
- ** # trackType/Format data in the data chunk
- ** + " " " that has to be generated
- ** * audio data as defined by the track infos chunk
- ** (a pause requested for the first audio track is valid and
- ** moves the audioStart)
- ** - audio data that has to be generated
- **
- ** #####################################+++------------------****************
- ** | | | | |
- ** startBlock <- preGapLen -> audioPregapStart audioStart
- ** <--- data track ---> <--- pregap (index 0) ---> <-- audio track
- **
- ** All these values are placed in this chunk:
- */
-
- #define ACD_DATATRACKINFOID 'CDTI'
-
- typedef struct {
- #ifdef ACD_CHUNK_HEADER
- ACD_ID ckID; /* 'CDTI' */
- ACD_LONG ckDataSize;
- #endif
-
- ACD_DataType trackType;
- ACD_DataFormat trackFormat;
- ACD_Block startBlock; /* usually #0 */
- ACD_ULONG preGapLen;
- ACD_Block audioPregapStart; /* >= startBlock + number of blocks */
- ACD_Block audioStart; /* > audioPregapStart */
-
- ACD_ULONG flags; /* none defined at the moment */
- ACD_ULONG reserved[4]; /* has to be set to 0 */
-
- #ifdef ACD_NON_C_DATATYPES
- pstring trackTypeName; /* from TypeNames */
- pstring dataFormatName; /* from FormatNames */
- #endif
-
- } ACD_DataTrackInfoChunk;
-
-
- /*
- ** This is the chunk for the track data itself. It has to be present if
- ** the data track is present.
- */
-
- #define ACD_DATATRACKDATAID 'CDDT'
-
- #ifdef ACD_NON_C_DATATYPES
- typedef struct
- {
- #ifdef ACD_CHUNK_HEADER
- ACD_ID ckID; /* 'CDDT' */
- ACD_LONG ckDataSize;
- #endif
-
- /* pure data - number of blocks can be calculated from
- ckDataSize and block size */
- char trackData[];
- } ACD_DataTrackDataChunk;
- #endif
-
- /*
- ** Future CD alike media (e.g. DVD) might contain too much blocks to count the
- ** number of bytes in ckDataSize. This document does not try to solve this
- ** problem, because the audio data storable in AIFF itself is already limited
- ** the same way.
- */
-
-
- /*
- ** Appendix I: example AIFF-CD file
- **
- ** This hex dump describes an audio CD with
- ** a medium catalog number ("9876543219876") and
- ** two tracks:
- ** 1. audio data without preamphasize,
- ** starting at CD block #32, length 10 seconds,
- ** no ISRC, indices relativ to track start:
- ** #1: 0 seconds (by definition of a track)
- ** #2: 2 seconds
- ** #3: 5 seconds
- ** no index pause
- ** 2. audio data with preamphasize,
- ** starting at CD block #782, length 10 seconds,
- ** ISRC "UK POH 98 12345", indices:
- ** #1: 0 seconds (s.o.)
- ** index pause: 8 seconds
- **
- ** AIFF form chunk:
- ** 464F524D 0035D5F4 41494646
- ** "FORM" length "AIFF"
- ** common chunk:
- ** 434F4D4D 00000012
- ** "COMM" length
- ** 0002 - 2 channels
- ** 000D7550 - 882000 sample frames = 20 seconds
- ** 0010 - 16 bit sampling size
- ** 400EAC44 00000000 0000 - frequency (see AIFF standard)
- ** track infos chunk:
- ** 54524946 0000004C
- ** "TRIF" length
- ** 00000001 - version 1 of AIFF-CD
- ** 00000001 - number of first track on CD
- ** 00000002 - two track in the file
- ** track infos for track #1:
- ** 00000020 - prepend pause of 32 blocks
- ** 00000000 - start at sample frame #0 in SSND chunk
- ** 0006BAA8 - 441000 sample frames long = 10 seconds
- ** 00000002 - flags: ACD_TRI_COPYRIGHTED
- ** 00000002 - two indices in addition to the obligatory one at the beginning
- ** 00000000 - number of reserved bytes: none
- ** 00000096 - indices at track block #150 = 2 seconds
- ** 00000177 - and at track block #375 = 5 seconds
- ** - _no_ index pause (ACD_TRI_PAUSE not set)
- ** 0000 - empty filename (length 0 + pad byte)
- ** no reserved bytes, track infos for track #2:
- ** 00000000 - no pause
- ** 0006BAA8 - start at sample frame #441000 = 10 seconds
- ** 0006BAA8 - 441000 sample frames long = 10 seconds
- ** 0000000B - flags: ACD_TRI_PREAMPHASIZE, ACD_TRI_COPYRIGHTED, ACD_TRI_PAUSE
- ** 00000001 - one index marker
- ** 00000000 - number of reserved bytes: none
- ** 00000258 - index _pause_ (ACD_TRI_PAUSE is set) at #600 = 8 seconds
- ** 0000 - empty filename
- ** medium catalog number chunk:
- ** 4D434E55 0000000E 39383736353433323139383736 00
- ** "MCNU" length "9876543219876" pad byte
- ** ISRC chunk:
- ** 49535243 00000014
- ** "ISRC" length
- ** 00000001 - one ISRC:
- ** 00000001 - track _index_ in infos array, i.e. ISRC is for track #2
- ** 554B 4F484C 3938 3132333435
- ** "UK OHL 98 12345"
- ** sound chunk:
- ** 53534E44 0035D548
- ** "SSND" length
- ** [3528008 bytes of audio data follow]
- */
-
- #endif /* AIFF_CD_H */
-